package br.com.sovi.gwt.client.cercaeletronica;

import java.util.ArrayList;
import java.util.List;

import br.com.sovi.gwt.client.cercaeletronica.service.CercaService;
import br.com.sovi.gwt.client.cercaeletronica.service.CercaServiceAsync;
import br.com.sovi.gwt.client.entity.Ponto;
import br.com.sovi.gwt.client.entity.cerca.Cerca;
import br.com.sovi.gwt.client.rpc.SecureAsyncCallback;
import br.com.sovi.gwt.client.ui.FormFactory;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.gwtext.client.widgets.Panel;

public class CercaMainMenuPanel extends Panel {

	private List<Cerca> cercas;

	private ListBox dispositivosBox;

	private final CercaHandler cercaHandler;

	private CercaServiceAsync service;

	private Button saveButton;

	private Button exibirButton;

	private Button limparButton;

	private Button deleteButton;

	public CercaMainMenuPanel(CercaHandler cercaHandler) {
		this.cercaHandler = cercaHandler;
		service = (CercaServiceAsync) GWT.create(CercaService.class);

		buildForm();
		initActions();
	}

	private void buildForm() {
		dispositivosBox = new ListBox(false);
		dispositivosBox.setTitle("Dispositivos");
		dispositivosBox.setWidth("100px");

		exibirButton = new Button("Exibir no Mapa");
		saveButton = new Button("Salvar Cerca");
		limparButton = new Button("Limpar Cerca");
		deleteButton = new Button("Remover Cerca");

		exibirButton.setWidth("99%");

		VerticalPanel panel = new VerticalPanel();
		panel.setSpacing(2);

		this.add(FormFactory.label("Dispositivos"));
		panel.add(dispositivosBox);
		panel.add(exibirButton);
		panel.add(saveButton);
		panel.add(limparButton);
		panel.add(deleteButton);

		this.add(panel);

		this.updateDispositivos();
	}

	private void initActions() {
		saveButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				final List<Ponto> pontos = CercaMainMenuPanel.this.cercaHandler.getPoints();
				Cerca cerca = new Cerca(dispositivosBox.getItemText(dispositivosBox.getSelectedIndex()), pontos);

				service.persistCerca(cerca, new SecureAsyncCallback<Void>() {
					@Override
					public void onSuccess(Void result) {
						final Cerca cerca = getSelectedCerca();
						cerca.setPoints(pontos);

						Window.alert("A cerca foi salva com sucesso.");
					}

					@Override
					public void onFailure(Throwable caught) {
						super.onFailure(caught);
						Window.alert("Ocorreu um erro ao tentar salvar a cerca.");
					}
				});

			}

		});

		exibirButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				final Cerca cerca = getSelectedCerca();

				if (cerca.getPoints() != null) {
					cercaHandler.showCerca(cerca);
				}
				else {
					service.getPontosFromCerca(cerca, new SecureAsyncCallback<List<Ponto>>() {
						@Override
						public void onSuccess(List<Ponto> result) {
							if (result != null) {
								cerca.setPoints(result);
								cercaHandler.showCerca(cerca);
							}
							else {
								Window.alert("Não foi encontrada uma cerca para este dispositivo.");
							}
						}

						@Override
						public void onFailure(Throwable caught) {
							super.onFailure(caught);
							Window.alert("Ocorreu um erro ao tentar exibir a cerca.");
						}
					});
				}

			}
		});

		limparButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				cercaHandler.clearCerca();
			}
		});

		deleteButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				service.deleteCercaFromDispositivo(getSelectedCerca().getSerial(), new SecureAsyncCallback<Boolean>() {
					@Override
					public void onFailure(Throwable caught) {
						super.onFailure(caught);
						Window.alert("Não foi possível remover a cerca deste dispositivo!");
					}

					@Override
					public void onSuccess(Boolean result) {
						Cerca cerca = getSelectedCerca();
						cerca.setPoints(null);
						cercaHandler.clearCerca();
						Window.alert("Cerca removida com sucesso!");
					}
				});
			}
		});

	}

	protected Cerca getSelectedCerca() {
		String text = dispositivosBox.getItemText(dispositivosBox.getSelectedIndex());

		for (Cerca cerca : cercas) {
			if (cerca.getSerial().equals(text)) {
				return cerca;
			}
		}

		return null;
	}

	protected void populateDispositivosBox(List<String> result) {
		for (String string : result) {
			dispositivosBox.addItem(string);
		}
	}

	public void updateDispositivos() {
		service.getAllDispositivos(new SecureAsyncCallback<List<Cerca>>() {
			@Override
			public void onSuccess(List<Cerca> result) {
				GWT.log("success: " + result.size(), null);
				cercas = result;

				List<String> ss = new ArrayList<String>();

				for (Cerca cerca : result) {
					GWT.log("success: " + cerca.getSerial(), null);
					ss.add(cerca.getSerial());
				}

				populateDispositivosBox(ss);
			}
		});
	}
}
